package com.cwt_taxi_xa.protocol.voice;

import android.util.Log;

import com.cwt_taxi_xa.constants.Constants;
import com.cwt_taxi_xa.constants.ConstantsEvaluate;
import com.cwt_taxi_xa.constants.MyStatus;
import com.cwt_taxi_xa.constants.SPConstants;
import com.cwt_taxi_xa.protocol.DispatchCenterUsers;
import com.cwt_taxi_xa.protocol.Encoder;
import com.cwt_taxi_xa.protocol.EncoderUtil;
import com.cwt_taxi_xa.protocol.MCUUtil;
import com.cwt_taxi_xa.protocol.card.cmd.BaseCmd;
import com.cwt_taxi_xa.service.FloatService;
import com.cwt_taxi_xa.service.SerialPortService;
import com.cwt_taxi_xa.util.AppLog;
import com.cwt_taxi_xa.util.ByteArrayUtil;
import com.cwt_taxi_xa.util.IntUtil;
import com.cwt_taxi_xa.util.SPUtils;
import com.cwt_taxi_xa.util.TTsFunction;
import com.cwt_taxi_xa.util.Tools;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

//		   帧投  	   cmd	 长度
//55F50015 AA(54 02)   DD 	 13 03 08 36 01 00 00 01 00 00 00 00 00 00  2E FF 6855
//					   checksum                        //
//					   校验码从帧长度到校验字节之前的数据依次异或运算和;
//		   AA55 	   A0 	 09 01 00 00 08 FF
// FocalAcoustics
public class VoiceTool{

	static String TAG = "VoiceTool";

	private boolean hasInstall = false;
	private boolean enableReceive = false;
	//打印升级帧前后4个字节
	public static int subLength = 4;

	public FocalAcousticsUpgrade focalAcousticsUpgrade = new FocalAcousticsUpgrade();


	public synchronized void onReceiveOrder(byte[] data){

		try {
			String order_str = Tools.parseByte2HexStr(data);
			Log.e(TAG,"读深耕数据-完整数据包 enableReceive:"+ enableReceive +"：-------------" + order_str);
			if(data != null && data.length > 7 ){
				if(data[0] == (byte)0xA5 && data[1] == (byte)0x0F && Constants.FOCAL_ACOUSTICS_ENABLE){
					if (data[5] == (byte) 0x0E) {
						Log.e(TAG,"JniInterface update success!");
						//10s后处理心跳,需要判断启动
						start();
					}
					focalAcousticsUpgrade.ackAndUpdate(data);
				}else if(data != null && (data[2] == 0x00) && (data[3]== 0x14)){
					AppLog.d(TAG,"onReceiveOrder startTimer");
					focalAcousticsUpgrade.deviceInfo(data);
					stopThread();
					//启动状态通知
					startTimer();
				}else if(data != null && (data[3]== 0x09)){
					AppLog.d(TAG,"onReceiveOrder voiceDecode");
					voiceDecode(data[2], IntUtil.littleBytesToInt16(Tools.byteTobyte(data,5,2)));
				}else{
					AppLog.d(TAG,"onReceiveOrder else");
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		//读深耕数据-完整数据包：-------------F50003E06C
		//MCU指令---声耕结果：E0
	}
	//0410  1004  4100  FocalAcoustics
	//AA55FF08010009FF 升级响应帧


	/**
	 * tsm905
	 *
	 * 添加包头尾、长度、0000、校验码
	 *
	 * @param data
	 * @return
	 */
	public static byte[] voiceEncode(int cmd,byte[] data) {
		byte[] bs = new byte[data.length + 7];//非数据部分7个
		bs[0] = (byte)0xAA;
		bs[1] = 0x55;
		bs[2] = (byte) cmd;//命令字
		bs[3] = (byte) bs.length;//帧长度  //帧长度指从帧头到帧尾的字节数之和
		bs[4] = 1;

		bs[bs.length - 2] = 0; 				//校验和   //校验码从帧长度到校验字节之前的数据依次异或运算和
		bs[bs.length - 1] = (byte) 0xFF;
		if(data.length > 0){
			System.arraycopy(data, 0, bs, 5, data.length);
		}

		for (int i = 3; i < bs.length - 2; i++) {
			bs[bs.length - 2] = (byte) (bs[bs.length - 2] ^ bs[i]);
			//AppLog.e(TAG,"voiceEncode HexString :" + Integer.toHexString(bs[bs.length - 2]));
		}
		return bs;
	}

	public static void voiceSend(int cmd){
		SerialPortService.getInstance().sendSerialData6(voiceEncode(cmd,new byte[]{}));
	}


	public static void voiceSend(int cmd,byte[] data){
		SerialPortService.getInstance().sendSerialData6(voiceEncode(cmd,data));
	}

	/**
	 * 车辆状态
	 * @param peopleNumber
	 * @param speed


	 */

	public static byte[] carInfoEncode(int peopleNumber,int speed,int signIn,int weightStatus,int overturnStatus,int doorStatus){
		byte[] data = new byte[12];
		//byte[] time = Tools.parseHexStr2Byte(DateUtil.getTimeDf19());
		byte[] time = getTime();
		System.arraycopy(time, 0, data, 0, time.length);

		data[3] = (byte)peopleNumber;
		data[4] = (byte)speed;
		data[5] = (byte)signIn;//0x01：司机签到 0x00：司机签退
		data[6] = (byte)weightStatus;//weightStatus：车内有无乘客 0x01：车内有乘客 0x00：车内无乘客
		data[7] = (byte)overturnStatus;//OverturnStatus：翻牌器状态 0x01：翻牌器翻下 0x00：翻牌器翻上
		data[8] = (byte)doorStatus;//DoorStatus：四个车门开关状态
		//bit0 ：1：主驾车门开 0：主驾车门关
		//bit1 ：1：副驾车门开 0：副驾车门关
		//bit2 ：1：主驾后车门开 0：主驾后车门关
		data[9] = 0;
		data[10] = 0;
		data[11] = 0;

		//SerialPortService.getInstance().sendSerialData6(voiceEncode(0xDD, data));
		return voiceEncode(0xDD, data);
// 		AA55  DD 13 03 09 31 14 000001000000000000 F0     FF
//		AA55  DD 13 01 0A 05 2B 0000 01 000000000000 37 FF
	}

	public static byte[] getTime(){
		Calendar c = Calendar.getInstance();//可以对每个时间域单独修改
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		return new byte[]{(byte)hour,(byte)minute,(byte)second};
	}

	/**
	 * 评价解析
	 * @param cmd
	 * @param value
	 */
	 final String[] courtesyArray = {"欢迎乘坐","目的地确认","安全乘坐提醒","打表计价提醒","下车检查提醒","拥堵绕路询问","制止吸烟A（司机）","制止吸烟B（乘客）"};
	 final String[] violationArray = {"无故拒载","故意绕路","强行拼车","不打表","中断服务","不按标准收费","未按规范标准服务","乘客投诉","紧急报警"};
	 final String[] evaluationArray = {"小静评价满意","小静评价一般","小静评价不满意"};
	private void voiceDecode(int cmd ,int value){

		Log.d(TAG,"voiceDecode cmd:" + Integer.toHexString(cmd) + " value:" + value);
		if(cmd == (byte)0xA0){
			//文明用语
			//0x00:欢迎乘坐
			//0x01:目的地确认
			//0x02:安全乘坐提醒
			//0x03:打表计价提醒
			//0x04:下车检查提醒
			//0x05:拥堵绕路询问
			//0x06:制止吸烟A（司机）
			//0x07:制止吸烟B（乘客）
			if(value < courtesyArray.length){
				//TTsFunction.speakText(courtesyArray[value]);
				AppLog.e(TAG,"voiceDecode 文明用语:" + courtesyArray[value]);
				if(value == 0){
					//ConstantsEvaluate.setEvaluateValue(value,1);
				}
			}else{
				AppLog.e(TAG,"voiceDecode 文明用语:" + value);
			}
		}else if(cmd == (byte)0xA1){
			//服务评价
			//0x00:满意
			//0x01:一般
			//0x02:不满意
			if(value < evaluationArray.length){
				//TTsFunction.speakText(evaluationArray[value]);
				AppLog.e(TAG,"voiceDecode 服务评价:" + evaluationArray[value]);
			}else{
				TTsFunction.speakText("超出评价服务评价范围");
				AppLog.e(TAG,"voiceDecode 服务评价:" + value);
			}
		}else if(cmd == (byte)0xA2){
			//违规判定
			//0x00:无故拒载
			//0x01:故意绕路
			//0x02:强行拼车
			//0x03:不打表
			//0x04:中断服务
			//0x05:不按标准收费
			//0x06:未按规范标准服务
			//0x07:乘客投诉
			//0xFF:紧急报警

			if((byte)value == (byte)0xFF){
				ConstantsEvaluate.setEvaluateValue(8,1);
				dispatchViolation();
			}else if(value == 0x04){
				ConstantsEvaluate.setEvaluateValue(5,1);
			}else if(value == 0x05){
				ConstantsEvaluate.setEvaluateValue(4,1);
			}else if(value < 0x08){
				ConstantsEvaluate.setEvaluateValue(value,1);
			}
			//日志输出
			if (value < violationArray.length) {
				//ConstantsEvaluate.setEvaluateValue(value,1);
				//TTsFunction.speakText(violationArray[value]);
				AppLog.e(TAG,"voiceDecode 违规判定:" + violationArray[value]);
			} else {
				if((byte)value == (byte)0xFF){
					AppLog.e(TAG,"voiceDecode 违规判定:紧急报警");
				}else{
					AppLog.e(TAG,"voiceDecode 违规判定:" + value);
				}
			}

		}
	}

	/**
	 * 检查到求解信号,直接发出
	 */
	public void dispatchViolation(){
		try{
			//更新违规信息
			byte [] locationbyte = EncoderUtil.getLocationInformationByte();
			AppLog.d(TAG,"dispatchViolation locationbyte:" + (locationbyte == null ? "null" : Tools.parseByte2HexStr(locationbyte)));
			//组织附加信息字段
			byte[] heartBeatByte = Encoder.getLocationInformation(ByteArrayUtil.concatAll(locationbyte,MCUUtil.mVehicleInformation.getCanExtraInfo()));
			if(heartBeatByte != null){
				DispatchCenterUsers.witeMsgConnected(heartBeatByte);
			}else{
				AppLog.savelog("dispatchViolation heartBeatByte is null");
			}
		}catch (Exception e){
			e.printStackTrace();
		}
	}


	/**
	 * 重新发送升级帧
	 * @param buffer
	 */
	public static void sendSerialDataResend(byte[] buffer){
		if(buffer != null && buffer.length > 0){
			try {
				Log.d(TAG,"重发送声耕指令 " + (Tools.parseByte2HexStr(BaseCmd.byteToSubstring(buffer,buffer.length - 4,subLength))) + " length:" + ( buffer == null?"null":buffer.length));
			} catch (Exception e) {
				e.printStackTrace();
			}
			byte[] bufferCache = MCUUtil.getSerialMCUData(MCUUtil.touchuan(buffer));
			if(bufferCache != null){
				SerialPortService.getInstance().sendSerialData7(bufferCache);
			}
		}
	}


	public static void sendSerialData7(byte[] buffer){
		if(buffer != null && buffer.length > 0){
			Log.d(TAG,"发送声耕指令 length:" + ( buffer == null?"null":buffer.length)+ " :"+Tools.parseByte2HexStr(buffer));
			SerialPortService.getInstance().sendSerialData7(MCUUtil.getSerialMCUData(MCUUtil.touchuan(buffer)));
		}
	}

	/**
	 *
	 */
	public void updateFrame(){
		sendSerialData7(VoiceTool.voiceEncode(0xFF,new byte[]{}));
	}

	/**
	 * 查询帧
	 */
	private void inquiryDevice(){
		sendSerialData7(VoiceTool.voiceEncode(0,new byte[]{}));
	}

	/**
	 * 车辆状态
	 */
	private synchronized void crateInfoAndSend(){
		int peopleNumber = FloatService.peopleNumber;
		if(peopleNumber == 0){
			peopleNumber = MyStatus.zhongche ? 1:0;
		}
		//int peopleNumber = 1;
		int speed = (int)MCUUtil.mVehicleInformation.getVehicleSpeed();
		int signIn = (SPUtils.getParamBoolean(SPConstants.SPK_signin, true)? 1:0);
		//int weightStatus = (peopleNumber > 1 ? 1:0);
		int weightStatus = (peopleNumber > 1 ? 1:(MyStatus.zhongche ? 1:0));
		int overturnStatus = (SPUtils.getParamBoolean(SPConstants.SPK_signin, true)?(MyStatus.zhongche ? 1:0):0xFF);//翻牌

		int leftFrontDoor = 0;//主驾驶车门,没有数据
		int rightFrontDoor = MCUUtil.mVehicleInformation.getRightFrontDoor();//副驾驶车门
		int rightBackDoor = MCUUtil.mVehicleInformation.getRightBackDoor();//副驾驶后车门
		int leftBackDoor = MCUUtil.mVehicleInformation.getLeftBackDoor();//主驾驶后车门
		int doorStatus = (leftFrontDoor | (rightFrontDoor<< 1)|(rightBackDoor << 2)|(leftBackDoor << 3));

		//AppLog.d(TAG,"crateInfoAndSend:" + Tools.parseByte2HexStr(VoiceTool.carInfoEncode(peopleNumber,speed,signIn,weightStatus,overturnStatus,doorStatus)));
		//AppLog.d(TAG,"crateInfoAndSend:" + Tools.parseByte2HexStr(VoiceTool.carInfoEncode(peopleNumber,speed,signIn,weightStatus,overturnStatus,doorStatus)));
		byte[] buffer = MCUUtil.getSerialMCUData(MCUUtil.touchuan(VoiceTool.carInfoEncode(peopleNumber,speed,signIn,weightStatus,overturnStatus,doorStatus)));

		SerialPortService.getInstance().sendSerialData7(buffer);
	}



	/**
	 * 打开通道,设置波特率
	 */
	public void start(){

		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					//enableReceive = false;
					if(!hasInstall){
						Thread.sleep(2000);
						MCUUtil.setIO(2,true);	//拉高IO口,供电声耕
						//Thread.sleep(2000);
						//MCUUtil.dataSerialConfig();			//配置MCU5路串口波特率
						hasInstall = true;
					}
					Thread.sleep(10*1000);		//声耕需要10m启动时间
					//enableReceive = true;
					inquiryDevice();//查询到设备后
					startThread();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	Thread inquiryThread;

	/**
	 * 查询帧
	 */
	private synchronized void startThread(){
		stopThread();
		if(inquiryThread == null){
			inquiryThread = new Thread(new Runnable() {
				int cont = 3;
				@Override
				public void run() {
					int index = 0;
					while (!Thread.currentThread().isInterrupted() && index < cont){
						try {
							Thread.sleep(2000);
							inquiryDevice();
							index ++;
							if(index == cont){
								Thread.sleep(2000);
								//设置没有找到设备
								focalAcousticsUpgrade.setHasDevice(false);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
							break;
						}
					}
				}
			});
			inquiryThread.start();
		}
	}


	private synchronized void stopThread(){
		if(inquiryThread != null){
			inquiryThread.interrupt();
			inquiryThread = null;
		}
	}

	Timer timer;

	TimerTask timerTask;

	private synchronized void startTimer(){
		closeTimer();
		if(timer == null){
			timer = new Timer();
			timerTask = new TimerTask() {
				@Override
				public void run() {
					crateInfoAndSend();
				}
			};
			timer.schedule(timerTask,1000,1000);
		}
	}

	public synchronized void closeTimer(){
		try {
			if(timer != null){
				timer.cancel();
			}
			if(timerTask != null){
				timerTask.cancel();
			}
			timer = null;
			timerTask = null;
		} catch (Exception e) {
			e.printStackTrace();
		}

	}


}
